/**
 *
 */
package com.cmcc.pcap.packet.sctp;

import com.cmcc.packet.entity.NGAP.NgapEntity;
import com.cmcc.packet.entity.SctpEntity;
import com.cmcc.pcap.packet.capture.HandlerManager;
import com.cmcc.pcap.packet.capture.JCaptures;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Date 2018年1月16日 下午7:45:07
 * @author Amish
 *
 */
public class SctpProtocolDispatcher implements Runnable {
    private static Logger logger = LogManager.getLogger(SctpProtocolDispatcher.class);
    boolean flag = true;//忘了干啥用的了....

    SctpConnectionCache sctpConnectionCache;

    private HashMap<String, SctpProtocolHandler> hashmap;
    private String taskId;
    JCaptures jCaptures;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public SctpProtocolDispatcher(JCaptures jCaptures, SctpConnectionCache sctpConnectionCache) {
    	this.jCaptures = jCaptures;
        this.sctpConnectionCache = sctpConnectionCache;
        this.hashmap = new HashMap<>();
    }

    /**
     * 用于识别TCP的应用层协议，并返回对应的Handler
     * @return
     */
    private SctpProtocolHandler distinguishSctpProtocol(SctpConnection sctpConnection) {
        //根据TcpProtocolFilter的结果，直接判断TcpConnection中的对应成员变量
        switch (sctpConnection.protocol) {
            case SCTP:{
                if (hashmap.containsKey("SCTP")) {
                    return hashmap.get("SCTP");
                } else {
                    try {
                        hashmap.put("SCTP", HandlerManager.getSctpHandler("sctp"));
                    } catch (IllegalAccessException | InstantiationException e) {
                        logger.error("new sctpHandler exception:" + e);
                    }
                    return hashmap.get("SCTP");
                }
            }

            case NGAP:{
                if (hashmap.containsKey("NGAP")) {
                    return hashmap.get("NGAP");
                } else {
                    try {
                        hashmap.put("NGAP", HandlerManager.getSctpHandler("ngap"));
                    } catch (IllegalAccessException | InstantiationException e) {
                        logger.error("new sctpHandler exception:" + e);
                    }
                    return hashmap.get("NGAP");
                }
            }


            default:
                //return new DefaultProtocolHandler();
                logger.info("Can not dispatcher protocol : " + sctpConnection.protocol.name() + " with first seq num : " + sctpConnection.al.get(0).sctpPacket.getHeader().getVerificationTag());
                return null;
        }
    }

    @Override
    public void run() {
        while (this.flag) {
            ArrayList<SctpConnection> al = this.sctpConnectionCache.getSctpConnection();//此处由于同步 可能阻塞
            //int totalHandledPacketNum = 0;
            for (SctpConnection sctpConnection : al) {
                int handledPacketNum = sctpConnection.al.size();//提前获取需要处理的Packet数量，TOFIX何时清零的？
                try {
                    SctpProtocolHandler sctpProtocolHandler = distinguishSctpProtocol(sctpConnection);
                    if (sctpProtocolHandler != null) {
                    	String protocolStr= sctpProtocolHandler.getClass().toString();
                        String protocolString=protocolStr.substring(protocolStr.lastIndexOf(".")+1);
						if(protocolString.equals("SctpHandler")) {
							List<SctpEntity> xdrList = sctpProtocolHandler.handle(sctpConnection,taskId);
							if(xdrList!=null&&xdrList.size()!=0) {
								jCaptures.sctpcallBack.action(xdrList);
							}
						}
                        if(protocolString.equals("NgapHandler")){
                            List<NgapEntity> xdrList = sctpProtocolHandler.handle(sctpConnection,taskId);
                            if(xdrList!=null&&xdrList.size()!=0) {
                                jCaptures.ngapcallBack.action(xdrList);
                            }
                        }
                    } else {
                        //logger.error("Can not the protocol handler");
                    }
                } catch (Exception e) {
                    logger.error(e.getCause(), e);
                } finally {
                    //totalHandledPacketNum += handledPacketNum;
                    sctpConnectionCache.handledPacketNum.getAndAdd(handledPacketNum);//记录已经处理的Packet数量
                }

            }
            //TODO TOFIX lvpin 20180619 如果写库操作放在这里，应该在写库操作完成后，使用totalHandledPacketNum来计数，否则可能导致提前结束处理

        }
    }

    public void terminate() {
        this.flag = false;
    }


}
